S&P 500の過去データにレバレッジをかけて観察する
現在の算出方式は、1941年から1943年における平均指数を10として、1957年3月4日からスタートしています。
S&P 500®は1957年3月4日に指数の算出を開始
1957年以前のデーターは、現在のS&P500の前身の指標となります。
現在の算出方式は、1941年から1943年における平均指数を10として、1957年3月4日からスタートしています。
素直に書くとこうなる
https://gyazo.com/b6a98088585093826b10e7c96f03c34b
GPT-4.icon基本的なGBMモデルでは、期待リターンやボラティリティは全体での平均値を使用することが一般的です
https://gyazo.com/09b4fbe676e28e2f7507c6296646bb45
正規化したS&P500と近似直線
切片 −0.211
傾き 約 0.000278
https://gyazo.com/37015054b529c9d2c324ce3d7ec463b3
1997年からの実際のS&P 500データに基づいて計算した結果
μ(期待リターンの平均):0.0343%
σ(日次リターンの標準偏差):1.24%
始点をどこに取るかで結果が大きく変わる
2001年(ITバブル崩壊直前)からやっていたら3xよりもレバなしの方が高い
https://gyazo.com/23280b4e6ce6e03cf27611074a175089
1990年からやっていれば3倍が一番高い
https://gyazo.com/139ecff8c86dee4e9587e8c9576e8390
この場合にレバの商品に手数料が年利1%取られると
https://gyazo.com/579a8880f82953295b53f7abc8e487c5
--.icon
https://gyazo.com/09b4fbe676e28e2f7507c6296646bb45
code:対数グラフ.py
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from numpy.polynomial.polynomial import Polynomial
# Read the S&P 500 data
df = pd.read_csv('/path/to/your/csv/file.csv')
# Filter the data to start from March 4, 1957
df_1957 = df[df'Date' >= '1957-03-04'].reset_index(drop=True) # Convert the dates to numerical values (number of days since March 4, 1957)
x_data = np.arange(len(df_1957))
# Normalize the S&P 500 data to start from 1
# Fit a first-degree polynomial (a line) to the logarithmic data
p = Polynomial.fit(x_data, np.log(normalized_s_1957), 1)
# Generate y-values based on the fit
y_fit_log = p(x_data)
# Plotting the logarithmic graph and the fitted line
plt.figure(figsize=(15, 6))
plt.semilogy(x_data, normalized_s_1957, label='Normalized Actual S&P 500 (Log scale)', color='b')
plt.semilogy(x_data, np.exp(y_fit_log), label=f'Fitted Line', color='r')
plt.title('Logarithmic Plot of the Normalized Actual S&P 500 and Fitted Line (Starting from March 4, 1957)')
plt.xlabel('Number of Days')
plt.ylabel('Close Price (Log Scale, Normalized)')
plt.legend()
plt.grid(True)
plt.show()
# Show the coefficients of the fitted line
print("Coefficients of the fitted line:", p.convert().coef)
https://gyazo.com/579a8880f82953295b53f7abc8e487c5
code:手数料あり.py
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# Read the S&P 500 data
df = pd.read_csv('/path/to/your/csv/file.csv')
# Filtering the dataset to only include data from January 1, 1990, onwards
df_1990 = df[df'Date' >= '1990-01-01'].reset_index(drop=True) # Number of data points in the dataset starting from 1990
n_1990 = len(df_1990)
# Calculate the daily returns for the actual S&P 500 data starting from 1990
s_actual_1990 = df_1990'Close'.values daily_returns_1990 = (s_actual_19901: / s_actual_1990:-1) - 1 # Define the annual fee rate for 2x, 3x, and 4x leveraged products (1% annual fee)
annual_fee_rate = 0.01
daily_fee_multiplier = 1 - (annual_fee_rate / 252) # Assuming 252 trading days in a year
# Initialize arrays for 2x, 3x, and 4x leveraged products with daily rebalancing and fees starting from 1990
s_2x_leverage_daily_rebalance_fee_1990 = np.zeros(n_1990)
s_3x_leverage_daily_rebalance_fee_1990 = np.zeros(n_1990)
s_4x_leverage_daily_rebalance_fee_1990 = np.zeros(n_1990)
s_2x_leverage_daily_rebalance_fee_19900 = s_actual_19900 s_3x_leverage_daily_rebalance_fee_19900 = s_actual_19900 s_4x_leverage_daily_rebalance_fee_19900 = s_actual_19900 # Perform the simulation with daily rebalancing and fees
for t in range(1, n_1990):
daily_return = (s_actual_1990t / s_actual_1990t-1) - 1 s_2x_leverage_daily_rebalance_fee_1990t = s_2x_leverage_daily_rebalance_fee_1990t-1 * (1 + 2 * daily_return) * daily_fee_multiplier s_3x_leverage_daily_rebalance_fee_1990t = s_3x_leverage_daily_rebalance_fee_1990t-1 * (1 + 3 * daily_return) * daily_fee_multiplier s_4x_leverage_daily_rebalance_fee_1990t = s_4x_leverage_daily_rebalance_fee_1990t-1 * (1 + 4 * daily_return) * daily_fee_multiplier # Normalize the leveraged products and actual S&P 500 to start from 100
normalized_s_actual_1990 = s_actual_1990 / s_actual_19900 * 100 normalized_s_2x_leverage_daily_rebalance_fee_1990 = s_2x_leverage_daily_rebalance_fee_1990 / s_2x_leverage_daily_rebalance_fee_19900 * 100 normalized_s_3x_leverage_daily_rebalance_fee_1990 = s_3x_leverage_daily_rebalance_fee_1990 / s_3x_leverage_daily_rebalance_fee_19900 * 100 normalized_s_4x_leverage_daily_rebalance_fee_1990 = s_4x_leverage_daily_rebalance_fee_1990 / s_4x_leverage_daily_rebalance_fee_19900 * 100 # Plotting the graph
plt.figure(figsize=(15, 6))
plt.plot(df_1990'Date', normalized_s_actual_1990, label='Normalized Actual S&P 500', color='r') plt.plot(df_1990'Date', normalized_s_2x_leverage_daily_rebalance_fee_1990, label='Normalized 2x Leveraged with Fee (Daily Rebalance)', color='g') plt.plot(df_1990'Date', normalized_s_3x_leverage_daily_rebalance_fee_1990, label='Normalized 3x Leveraged with Fee (Daily Rebalance)', color='b') plt.plot(df_1990'Date', normalized_s_4x_leverage_daily_rebalance_fee_1990, label='Normalized 4x Leveraged with Fee (Daily Rebalance)', color='m') plt.title('Normalized Actual S&P 500, 2x, 3x, and 4x Leveraged with Daily Rebalancing and Fees (Base Value = 100, Starting from 1990)')
plt.xlabel('Date')
plt.ylabel('Normalized Value')
plt.legend()
plt.grid(True)
plt.show()
https://gyazo.com/37015054b529c9d2c324ce3d7ec463b3
1997年からの実際のS&P 500データに基づいて計算した結果
μ(期待リターンの平均):0.0343%
σ(日次リターンの標準偏差):1.24%
code:py
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# Load the data
df = pd.read_csv('/path/to/data.csv')
# Filter data starting from 1997
df_1997 = df[df'Date' >= '1997-01-01'].reset_index(drop=True) # Initialize arrays and variables
n_1997 = len(df_1997)
s_actual_1997 = df_1997'Close'.values # Normalize the actual S&P 500
normalized_s_actual_1997 = s_actual_1997 / s_actual_19970 * 100 # Initialize arrays for 2x, 3x, and 4x leveraged products
s_2x_leverage_daily_rebalance_1997 = np.zeros(n_1997)
s_3x_leverage_daily_rebalance_1997 = np.zeros(n_1997)
s_4x_leverage_daily_rebalance_1997 = np.zeros(n_1997)
s_2x_leverage_daily_rebalance_19970 = s_actual_19970 s_3x_leverage_daily_rebalance_19970 = s_actual_19970 s_4x_leverage_daily_rebalance_19970 = s_actual_19970 # Perform daily rebalancing for 2x, 3x, and 4x leveraged products
for t in range(1, n_1997):
daily_return = (s_actual_1997t / s_actual_1997t-1) - 1 s_2x_leverage_daily_rebalance_1997t = s_2x_leverage_daily_rebalance_1997t-1 * (1 + 2 * daily_return) s_3x_leverage_daily_rebalance_1997t = s_3x_leverage_daily_rebalance_1997t-1 * (1 + 3 * daily_return) s_4x_leverage_daily_rebalance_1997t = s_4x_leverage_daily_rebalance_1997t-1 * (1 + 4 * daily_return) # Normalize the leveraged products
normalized_s_2x_leverage_daily_rebalance_1997 = s_2x_leverage_daily_rebalance_1997 / s_2x_leverage_daily_rebalance_19970 * 100 normalized_s_3x_leverage_daily_rebalance_1997 = s_3x_leverage_daily_rebalance_1997 / s_3x_leverage_daily_rebalance_19970 * 100 normalized_s_4x_leverage_daily_rebalance_1997 = s_4x_leverage_daily_rebalance_1997 / s_4x_leverage_daily_rebalance_19970 * 100 # Plotting
plt.figure(figsize=(15, 6))
plt.plot(df_1997'Date', normalized_s_actual_1997, label='Normalized Actual S&P 500', color='r') plt.plot(df_1997'Date', normalized_s_2x_leverage_daily_rebalance_1997, label='Normalized 2x Leveraged (Daily Rebalance)', color='g') plt.plot(df_1997'Date', normalized_s_3x_leverage_daily_rebalance_1997, label='Normalized 3x Leveraged (Daily Rebalance)', color='b') plt.plot(df_1997'Date', normalized_s_4x_leverage_daily_rebalance_1997, label='Normalized 4x Leveraged (Daily Rebalance)', color='m') plt.title('Normalized Actual S&P 500, 2x, 3x, and 4x Leveraged with Daily Rebalancing (Base Value = 100, Starting from 1997)')
plt.xlabel('Date')
plt.ylabel('Normalized Value')
plt.legend()
plt.grid(True)
plt.show()